package com.cloud.scope;

import com.cloud.common.enums.ScopeType;
import com.cloud.domain.BaseEntity;
import com.cloud.domain.LoginUser;
import com.cloud.utils.*;
import org.apache.commons.lang3.ObjectUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 数据过滤处理
 *
 * @author yzj
 */
@Aspect
@Component
public class DataScopeAspect {

    /**
     * 配置切入点
     */
    @Pointcut("@annotation(com.cloud.scope.DataScope)")
    public void dataScopePoint() {
    }

    @Before("dataScopePoint()")
    public void doBefore(JoinPoint point) {
        if (!SystemUtils.isAdmin(SecurityUtils.getUserId())) {
            clearDataScope(point);
            handleDataScope(point);
        }
    }

    protected void handleDataScope(final JoinPoint joinPoint) {
        DataScope dataScope = getAnnotationLog(joinPoint);
        if (dataScope == null) {
            return;
        }
        // 获取当前的用户登录信息
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (ObjectUtils.isNotEmpty(loginUser)) {
            dataScopeFilter(joinPoint, loginUser, dataScope.deptAlias(), dataScope.deptField(),
                    dataScope.userAlias(), dataScope.userField());
        }
    }

    /**
     * 数据范围过滤
     *
     * @param joinPoint 切点
     * @param loginUser 登录用户
     * @param userAlias 别名
     */
    public void dataScopeFilter(JoinPoint joinPoint, LoginUser loginUser,
                                String deptAlias, String deptField, String userAlias, String userField) {
        // 设置账户角色数据权限
        StringBuilder builder = SQLFilterUtils.setDataScope(loginUser, deptAlias, deptField, userAlias, userField);
        if (StringUtils.isNotBlank(builder)) {
            Object params = joinPoint.getArgs()[0];
            if (StringUtils.isNotNull(params) && params instanceof BaseEntity) {
                BaseEntity baseEntity = (BaseEntity) params;
                baseEntity.getAskParam().put(ScopeType.DATA_SCOPE.getCode(),
                        " AND (" + builder.substring(4) + ")");
            }
        }
    }

    /**
     * 是否存在注解，如果存在就获取
     */
    private DataScope getAnnotationLog(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        if (method != null) {
            return method.getAnnotation(DataScope.class);
        }
        return null;
    }

    /**
     * 拼接权限sql前先清空params.dataScope 参数防止注入
     */
    private void clearDataScope(final JoinPoint joinPoint) {
        if (ObjectUtils.isNotEmpty(joinPoint.getArgs())) {
            Object params = joinPoint.getArgs()[0];
            if (StringUtils.isNotNull(params) && params instanceof BaseEntity) {
                BaseEntity baseEntity = ToolUtils.strongTurn(params);
                baseEntity.getAskParam().put(ScopeType.DATA_SCOPE.getCode(), "");
            }
        }
    }

}
